﻿namespace Resharper.Abstractions.CodeDom.TypeMembers
{
  using System;
  using JetBrains.Annotations;
  using JetBrains.ReSharper.Psi.Tree;
  using Resharper.Abstractions.Actions;
  using Resharper.Abstractions.CodeDom.TreeNodes;
  using Resharper.Abstractions.CodeDom.TypeMembers.Fields.Constants;

  /// <summary>Defines the <see cref="ConstantExtensions"/> class.</summary>
  public static class TypeMemberExtensions
  {
    #region Public Methods

    /// <summary>Creates the constant.</summary>
    /// <param name="factory">The factory.</param>
    /// <param name="code">The code.</param>
    /// <returns>Returns the constant.</returns>
    public static TypeMember CreateTypeMember([NotNull] this Factory factory, [NotNull] string code)
    {
      if (factory == null)
      {
        throw new ArgumentNullException("factory");
      }

      if (code == null)
      {
        throw new ArgumentNullException("code");
      }

      var typeMember = factory.InternalFactory.CreateTypeMemberDeclaration(code);

      return TypeMemberFactory.GetTypeMember(typeMember);
    }

    /// <summary>Gets the containing type member.</summary>
    /// <param name="treeNode">The tree node.</param>
    /// <returns>Returns the containing type member.</returns>
    [CanBeNull]
    public static TypeMember GetContainingTypeMember([NotNull] this TreeNode treeNode)
    {
      if (treeNode == null)
      {
        throw new ArgumentNullException("treeNode");
      }

      var typeMember = treeNode.InternalTreeNode.GetContainingNode<ITypeMemberDeclaration>();

      return typeMember != null ? TypeMemberFactory.GetTypeMember(typeMember) : null;
    }

    /// <summary>Gets the selected type member.</summary>
    /// <param name="context">The context.</param>
    /// <returns>Returns the selected type member.</returns>
    public static TypeMember GetSelectedTypeMember([NotNull] this ProviderContext context)
    {
      if (context == null)
      {
        throw new ArgumentNullException("context");
      }

      var typeMember = context.InternalGetSelectedElement<ITypeMemberDeclaration>();

      return typeMember != null ? TypeMemberFactory.GetTypeMember(typeMember) : null;
    }

    #endregion
  }
}